import { ServiceException } from './../service/serviceException';
import { OrderService } from './../service/orderService';
import { Order } from './../domain/model/order';
import { KitchensolutionService } from './../service/kitchensolutionService';
import { KitchenOrderService } from './../service/kitchenOrderService';
import { Response, ServiceConfig, route, Guid, uniqueArray, intersectionArray } from '../common';
import { KitchenOrder } from '../domain/model';
import { WebException } from './webException';
import assert = require("assert");
import * as Koa from "koa";
import * as R from "ramda";

export class KDSOrderController {
    private kitchensOrderSvr: KitchenOrderService;
    private kitchensolutionService: KitchensolutionService;
    private orderService: OrderService;
    constructor() {
        this.kitchensOrderSvr = ServiceConfig.Current.GetService<KitchenOrderService>("kitchenOrderService");
        this.kitchensolutionService = ServiceConfig.Current.GetService<KitchensolutionService>("kitchensolutionService");
        this.orderService = ServiceConfig.Current.GetService<OrderService>("orderService");
    }

    toString(){
        return "KDSOrderController";
    }

    /**
    * 测试url
    * @memberOf kdsOrderController
    */
    @route({ method: "get", path: "/api/kitchenOrders/success" })
    async test(ctx: Koa.Context, next) {
        ctx.response.body = Response.ok("success", {});
        await next();
    }

    //新增一个kitchenOrder
    @route({ method: "post", path: "/api/kitchenOrders/" })
    private async addKitchenOrder(ctx: Koa.Context, next) {
        let kitchenOrder: KitchenOrder = ctx.request.body.kitchenOrder;
        const stalls = ctx.request.body.stalls;
        const allKdsKitchensolutions = await this.kitchensolutionService.getAllKdsKitchensolutions();
        const generateKitchenOrder = R.curry(this.generateKitchenOrderByOrderId)(allKdsKitchensolutions).bind(this);
        let orders:Array<Order>;
        if (kitchenOrder.type == "pre-order-refund" || kitchenOrder.type == "pickup-order") {
          const orderIds = kitchenOrder.originalOrderIds;
          orders = await Promise.all(orderIds.map(id => generateKitchenOrder(id))).then(kitchenOrders=>kitchenOrders.filter(x=>x));
        } else if(kitchenOrder.type == "remind-order"){
            const orderIds = await Promise.all(kitchenOrder.originalOrderIds.map(id=>this.getOrderByOrderId(id))).then(orders=>{
               return orders.filter(order=>order.orderType != "pre-order-refund" && order.orderType !="refund").map(order=>order.id)
            }) ;
            orders = await this.kitchensOrderSvr.remindOrdersByOrderIds(orderIds, kitchenOrder.items);
        }else {
            const orderIds = [kitchenOrder.orderId];
            orders = await Promise.all(orderIds.map(id => generateKitchenOrder(id))).then(kitchenOrders=>kitchenOrders.filter(x=>x));
        }
         
        ctx.response.body = Response.ok("添加订单成功", { orders });
        await next();
    }

    //获取一个订单
    @route({ method: "get", path: "/api/kitchenOrders/:id/" })
    private async getKitchenOrder(ctx: Koa.Context, next) {
        const id = ctx.params.id;
        const order = await this.kitchensOrderSvr.getKitchenOrderById(id);
        ctx.response.body = Response.ok("厨房订单查询成功", order);
    }
    //批量完成一个订单项
    @route({ method: "post", path: "/api/kitchenOrders/:id/cartItems/batch/finish" })
    private async finishKitchenOrderCartItems(ctx: Koa.Context, next) {
        const id = ctx.params.id;
        const itemIds = ctx.request.body.itemIds;
        const order = await this.kitchensOrderSvr.finishKitchenOrderItemsByItemIds(id, itemIds);
        ctx.response.body = Response.ok("批量完成订单成功", order);
    }

    //完成一个订单的某一项
    @route({ method: "post", path: "/api/kitchenOrders/:id/cartItems/:cartItemId/finish" })
    private async finishKitchenOrderCartItem(ctx: Koa.Context, next) {
        const id = ctx.params.id;
        const cartItemId = ctx.params.cartItemId;
        const order = await this.kitchensOrderSvr.finishKitchenOrderItem(id, cartItemId);
        ctx.response.body = Response.ok("完成订单成功", order);
    }

    //取消完成一个订单的某一项
    @route({ method: "post", path: "/api/kitchenOrders/:id/cartItems/:cartItemId/unFinish" })
    private async unFinishKitchenOrderItem(ctx: Koa.Context, next) {
        const id = ctx.params.id;
        const cartItemId = ctx.params.cartItemId;
        const order = await this.kitchensOrderSvr.unFinishKitchenOrderItem(id, cartItemId);
        ctx.response.body = Response.ok(" 取消完成订单成功", order);
    }

    //出品一个订单的项
    @route({ method: "post", path: "/api/kitchenOrders/:id/finish" })
    private async finishKitchenOrder(ctx: Koa.Context, next) {
        const storeId = ctx.accept.headers["storeid"];
        const terminal = ctx.request.body.terminal;
        const user = ctx.request.body.user;

        const id = ctx.params.id;
        const itemIds = ctx.request.body.itemIds;
        const stalls = ctx.request.body.stalls;

        const order = await this.kitchensOrderSvr.finishKitchenOrderByItemIds(id, itemIds);
        const retOrder = this.kitchensOrderSvr.initKitchenOrderLocalStall(order, stalls);
        ctx.response.body = Response.ok("完成订单成功", order);
    }

    //出品一个订单的项
    @route({ method: "post", path: "/api/kitchenOrders/:id/close" })
    private async closeKitchenOrder(ctx: Koa.Context, next) {
        const storeId = ctx.accept.headers["storeid"];
        const terminal = ctx.request.body.terminal;
        const user = ctx.request.body.user;

        const id = ctx.params.id;
        const itemIds = ctx.request.body.itemIds;

        const order = await this.kitchensOrderSvr.closeOrderByItemIds(id, itemIds);
        ctx.response.body = Response.ok("关闭订单成功", order);
    }

    //获取所有的订单   
    @route({ method: 'get', path: '/api/kitchenOrders' })
    private async getOrders(ctx: Koa.Context, next) {
        const query = ctx.request.query;
        const paramsWhite = ["finishTime", "stalls", "beginFinishTime", "endFinishTime", "limit", "sortby", "order"];
        for (let key in query) {
            if (paramsWhite.indexOf(key) == -1) {
                throw new WebException( key + "参数不合法");
            }
        }
        //转换url
        if (query.stalls && !Array.isArray(query.stalls)) {
            query.stalls = [query.stalls]
        }
        if (query.beginFinishTime) {
            query.beginFinishTime = Number(query.beginFinishTime);
        }
        if (query.endFinishTime) {
            query.endFinishTime = Number(query.endFinishTime);
        }
        if (query.limit) {
            query.limit = Number(query.limit);
        }
        let retOrders: KitchenOrder[];
        if (Object.keys(query).length == 0) {
            retOrders = await this.kitchensOrderSvr.getAllKitchenOrders();
        } else {
            retOrders = await this.kitchensOrderSvr.queryKitchenOrders(query)
        }

        if (query.stalls) {
            retOrders.forEach(v => {
                v = this.kitchensOrderSvr.initKitchenOrderLocalStall(v, query.stalls);
            })
        }
        ctx.response.body = Response.ok("订单查询成功", retOrders);;
        await next();
    }



    /**
     * 订单检测
     * @param  {} order
     */
    private checKitchenOrder(kitchenOrder) {
        assert.notEqual(kitchenOrder, null, "下单失败，无订单信息");
        assert.notEqual(kitchenOrder.items, null, "下单失败，购物车无商品");
        assert.notEqual(kitchenOrder.orderId, null, "下单失败，无原始订单ID");
        assert.notEqual(kitchenOrder.seriaNo, null, "下单失败，无流水号信息");
    }

    async getOrderByOrderId(orderId){
         const order = await this.orderService.GetOrderById(orderId);
        if (!order) throw new ServiceException(this, orderId + "订单没有找到");
         return order;
    }

    async generateKitchenOrderByOrderId(allKdsKitchensolutions, orderId): Promise<KitchenOrder> {
       const order = await this.getOrderByOrderId(orderId);
                //退单不要丽
        if(order.orderType == "pre-order-refund" || order.orderType == "refund"){
            return null;
        }
        const resKitchenOrder = await this.kitchensOrderSvr.putKitchenOrderByOrder(allKdsKitchensolutions, order);
        return resKitchenOrder;
    }

}
